$import( "SmitearWebGL.Programs.AbstractProgram" );

SmitearWebGL.Programs.Hdr.CombineProgram = SmitearWebGL.Programs.AbstractProgram.extend(
{
	/******** constructor ********/

	init : function()
	{
		this._super();
		this._registClass( "SmitearWebGL.Programs.Hdr.CombineProgram" );
	}
	,

	/******** public method ********/

	activeUniform : function( renderableObject )
	{
		this.context.gl.uniform1f( this._shader.uniforms.uExposure.location, SmitearWebGL.Objects.Canvas.Hdr.Combine.Exposure );
		this.context.gl.uniform1f( this._shader.uniforms.uGaussianScalar.location, SmitearWebGL.Objects.Canvas.Hdr.Blur.GaussMultiplier );
		
		
		var texture = renderableObject.getTextureAt( 0 );
		this.context.gl.activeTexture( this.context.gl.TEXTURE0 );
		this.context.gl.bindTexture( this.context.gl.TEXTURE_2D, texture.getGlTexture() );
		this.context.gl.uniform1i( this._shader.uniforms.uOriginal.location, 0 );
		
		texture = renderableObject.getTextureAt( 1 );
		this.context.gl.activeTexture( this.context.gl.TEXTURE1 );
		this.context.gl.bindTexture( this.context.gl.TEXTURE_2D, texture.getGlTexture() );
		this.context.gl.uniform1i( this._shader.uniforms.uLuminance.location, 1 );
		
		texture = renderableObject.getTextureAt( 3 );
		this.context.gl.activeTexture( this.context.gl.TEXTURE2 );
		this.context.gl.bindTexture( this.context.gl.TEXTURE_2D, texture.getGlTexture() );
		this.context.gl.uniform1i( this._shader.uniforms.uBloom.location, 2 );
		
		return SmitearWebGL.Core.HResult.SUCCESS;
	}
	,

	/******** private method ********/

	_generateVertexShaderStr : function()
	{
		this._super();

		var vertStr =
		"\
		attribute vec3 " + SmitearWebGL.Resources.Buffer.AttribLocation.POSITION +";\n\
		varying vec2 vTexCoord;\n\
		void main(void)\n\
		{\n\
			vec4 pos = vec4(" + SmitearWebGL.Resources.Buffer.AttribLocation.POSITION +", 1.0);\n\
			gl_Position = pos;\n\
			vTexCoord = vec2((pos.x + 1.0) * 0.5, (pos.y + 1.0) * 0.5);\n\
		}\n\
		";

		return vertStr;
	}
	,
	_generateFragmentShaderStr : function()
	{
		this._super();
		
		var fragStr = "";
		
		if ( this.context.capacity.supported.OES_texture_float )
		{
			fragStr =
			"\
			#ifdef GL_ES\n\
			precision highp float;\n\
			#endif\n\
			uniform sampler2D uBloom;\n\
			uniform sampler2D uOriginal;\n\
			uniform sampler2D uLuminance;\n\
			uniform float uExposure;\n\
			uniform float uGaussianScalar;\n\
			uniform float u_rcp_bloom_tex_w;\n\
			uniform float u_rcp_bloom_tex_h;\n\
			const vec4 lumfact = vec4(0.27,0.67,0.06,0.0);\n\
			varying vec2 vTexCoord;\n\
			void main(void) {\n\
				vec4 color = texture2D( uOriginal, vTexCoord );\n\
				color.a = 1.0;\n\
				vec4 lumMap = texture2D( uLuminance, vec2( 0.0, 0.0 ) );\n\
				float aveLum = lumMap.r;\n\
				float maxLum = lumMap.g;\n\
				vec4 bloomMap = texture2D( uBloom, vTexCoord );\n\
				vec4 final = color + bloomMap;\n\
				float Lp = (uExposure / aveLum) * dot(final, lumfact);\n\
				float LmSqr = (maxLum + uGaussianScalar * maxLum) * (maxLum + uGaussianScalar * maxLum);\n\
				float toneScalar = ( Lp * ( 1.0 + ( Lp / ( LmSqr ) ) ) ) / ( 1.0 + Lp );\n\
				color = final * toneScalar;\n\
				color.a = 1.0;\n\
				gl_FragColor = color;\n\
			}\n\
			";
		}
		else
		{
			fragStr =
			"\
			#ifdef GL_ES\n\
			precision highp float;\n\
			#endif\n\
			uniform sampler2D uBloom;\n\
			uniform sampler2D uOriginal;\n\
			uniform sampler2D uLuminance;\n\
			uniform float uExposure;\n\
			uniform float uGaussianScalar;\n\
			uniform float u_rcp_bloom_tex_w;\n\
			uniform float u_rcp_bloom_tex_h;\n\
			const vec4 lumfact = vec4(0.27,0.67,0.06,0.0);\n\
			varying vec2 vTexCoord;\n\
			void main(void) {\n\
				vec4 color = texture2D( uOriginal, vTexCoord );\n\
				color.rgb /= color.a;\n\
				color.a = 1.0;\n\
				vec4 lumMap = texture2D( uLuminance, vec2( 0.0, 0.0 ) );\n\
				float aveLum = lumMap.r / lumMap.b;\n\
				float maxLum = lumMap.g / lumMap.a;\n\
				vec4 bloomMap = texture2D( uBloom, vTexCoord );\n\
				vec4 final = color + bloomMap;\n\
				float Lp = (uExposure / aveLum) * dot(final, lumfact);\n\
				float LmSqr = (maxLum + uGaussianScalar * maxLum) * (maxLum + uGaussianScalar * maxLum);\n\
				float toneScalar = ( Lp * ( 1.0 + ( Lp / ( LmSqr ) ) ) ) / ( 1.0 + Lp );\n\
				color = final * toneScalar;\n\
				color.a = 1.0;\n\
				gl_FragColor = color;\n\
			}\n\
			";
		}
		
		return fragStr;
	}
//	,
//	_generateFragmentShaderStr : function()
//	{
//		this._super();
//
//		var fragStr =
//		"\
//		#ifdef GL_ES\n\
//		precision highp float;\n\
//		#endif\n\
//		uniform sampler2D uBloom;\n\
//		uniform sampler2D uOriginal;\n\
//		uniform sampler2D uLuminance;\n\
//		uniform float uExposure;\n\
//		uniform float uGaussianScalar;\n\
//		uniform float u_rcp_bloom_tex_w;\n\
//		uniform float u_rcp_bloom_tex_h;\n\
//		const vec4 lumfact = vec4(0.27,0.67,0.06,0.0);\n\
//		varying vec2 vTexCoord;\n\
//		void main(void) {\n\
//			vec4 color = texture2D( uOriginal, vTexCoord );\n\
//			color.rgb /= color.a;\n\
//			color.a = 1.0;\n\
//			vec4 lumMap = texture2D( uLuminance, vec2( 0.0, 0.0 ) );\n\
//			float aveLum = lumMap.r / lumMap.b;\n\
//			float lp = uExposure * dot(color, lumfact) / aveLum;\n\
//			float toneScalar = lp / ( 1.0 + lp );\n\
//			color *= toneScalar;\n\
//			gl_FragColor = color + texture2D( uBloom, vTexCoord );\n\
//		}\n\
//		";
//		
//		return fragStr;
//	}
}
);